package com.loong.tool.lang;

import java.lang.reflect.Field;

/**
 * 反射工具类
 *
 * @author 张成轩
 */
public class Reflects {

	/**
	 * 获取对象字段值
	 * 
	 * @param obj 对象
	 * @param name 字段名
	 * @return 字段值
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 * @throws NoSuchFieldException
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getFieldValue(Object obj, String name)
			throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException {

		Object result = null;
		Field field = getField(obj, name);
		field.setAccessible(true);
		result = field.get(obj);
		return (T) result;
	}

	/**
	 * 获取对象字段对象
	 * 
	 * @param obj 对象
	 * @param name 变量名
	 * @return 字段对象
	 * @throws NoSuchFieldException
	 */
	public static Field getField(Object obj, String name) throws NoSuchFieldException {

		Class<?> clazz = obj.getClass();
		try {
			return clazz.getDeclaredField(name);
		} catch (NoSuchFieldException | SecurityException e) {
		}
		// 遍历父类
		while (true) {
			clazz = clazz.getSuperclass();
			if (clazz == Object.class)
				break;
			try {
				return clazz.getDeclaredField(name);
			} catch (NoSuchFieldException | SecurityException e) {
			}
		}
		throw new NoSuchFieldException(name);
	}

	/**
	 * 设置对象字段值
	 * 
	 * @param obj 对象
	 * @param name 字段名
	 * @param value 字段值
	 * @throws NoSuchFieldException
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 */
	public static void setFieldValue(Object obj, String name, Object value)
			throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException {

		Field field = getField(obj, name);
		field.setAccessible(true);
		field.set(obj, value);
	}
}
